<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>DSF2FLAC: dsf_file_reader.cpp Source File</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />

<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>

</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">DSF2FLAC
   
   </div>
   
  </td>
  
  
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.6.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
      </li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>File&#160;Members</span></a></li>
    </ul>
  </div>
</div>
<div class="header">
  <div class="headertitle">
<div class="title">dsf_file_reader.cpp</div>  </div>
</div><!--header-->
<div class="contents">
<div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> * dsf2flac - http://code.google.com/p/dsf2flac/</span>
<a name="l00003"></a>00003 <span class="comment"> *</span>
<a name="l00004"></a>00004 <span class="comment"> * A file conversion tool for translating dsf dsd audio files into</span>
<a name="l00005"></a>00005 <span class="comment"> * flac pcm audio files.</span>
<a name="l00006"></a>00006 <span class="comment"> *</span>
<a name="l00007"></a>00007 <span class="comment"> * Copyright (c) 2013 by respective authors.</span>
<a name="l00008"></a>00008 <span class="comment"> *</span>
<a name="l00009"></a>00009 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
<a name="l00010"></a>00010 <span class="comment"> * it under the terms of the GNU General Public License as published by</span>
<a name="l00011"></a>00011 <span class="comment"> * the Free Software Foundation; either version 2 of the License, or</span>
<a name="l00012"></a>00012 <span class="comment"> * (at your option) any later version.</span>
<a name="l00013"></a>00013 <span class="comment"> *</span>
<a name="l00014"></a>00014 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
<a name="l00015"></a>00015 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00016"></a>00016 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<a name="l00017"></a>00017 <span class="comment"> * GNU General Public License for more details.</span>
<a name="l00018"></a>00018 <span class="comment"> *</span>
<a name="l00019"></a>00019 <span class="comment"> * You should have received a copy of the GNU General Public License</span>
<a name="l00020"></a>00020 <span class="comment"> * along with this program; if not, write to the Free Software</span>
<a name="l00021"></a>00021 <span class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</span>
<a name="l00022"></a>00022 <span class="comment"> *</span>
<a name="l00023"></a>00023 <span class="comment"> *</span>
<a name="l00024"></a>00024 <span class="comment"> * Acknowledgements</span>
<a name="l00025"></a>00025 <span class="comment"> *</span>
<a name="l00026"></a>00026 <span class="comment"> * Many thanks to the following authors and projects whose work has greatly</span>
<a name="l00027"></a>00027 <span class="comment"> * helped the development of this tool.</span>
<a name="l00028"></a>00028 <span class="comment"> *</span>
<a name="l00029"></a>00029 <span class="comment"> *</span>
<a name="l00030"></a>00030 <span class="comment"> * Sebastian Gesemann - dsd2pcm (http://code.google.com/p/dsd2pcm/)</span>
<a name="l00031"></a>00031 <span class="comment"> * SACD Ripper (http://code.google.com/p/sacd-ripper/)</span>
<a name="l00032"></a>00032 <span class="comment"> * Maxim V.Anisiutkin - foo_input_sacd (http://sourceforge.net/projects/sacddecoder/files/)</span>
<a name="l00033"></a>00033 <span class="comment"> * Vladislav Goncharov - foo_input_sacd_hq (http://vladgsound.wordpress.com)</span>
<a name="l00034"></a>00034 <span class="comment"> * Jesus R - www.sonore.us</span>
<a name="l00035"></a>00035 <span class="comment"> *</span>
<a name="l00036"></a>00036 <span class="comment"> */</span>
<a name="l00037"></a>00037 
<a name="l00051"></a>00051 <span class="preprocessor">#include &quot;dsf_file_reader.h&quot;</span>
<a name="l00052"></a>00052 <span class="preprocessor">#include &quot;taglib/tfile.h&quot;</span>
<a name="l00053"></a>00053 <span class="preprocessor">#include &quot;taglib/id3v2tag.h&quot;</span>
<a name="l00054"></a>00054 
<a name="l00055"></a>00055 <span class="keyword">static</span> <span class="keywordtype">bool</span> blockBufferAllocated = <span class="keyword">false</span>;
<a name="l00056"></a>00056 
<a name="l00062"></a>00062 dsfFileReader::dsfFileReader(<span class="keywordtype">char</span>* filePath) : DsdSampleReader()
<a name="l00063"></a>00063 {
<a name="l00064"></a>00064         this-&gt;filePath = filePath;
<a name="l00065"></a>00065         <span class="comment">// first let&#39;s open the file</span>
<a name="l00066"></a>00066         file.open(filePath, fstreamPlus::in | fstreamPlus::binary);
<a name="l00067"></a>00067         <span class="comment">// throw exception if that did not work.</span>
<a name="l00068"></a>00068         <span class="keywordflow">if</span> (!file.is_open()) {
<a name="l00069"></a>00069                 errorMsg = <span class="stringliteral">&quot;could not open file&quot;</span>;
<a name="l00070"></a>00070                 valid = <span class="keyword">false</span>;
<a name="l00071"></a>00071                 <span class="keywordflow">return</span>;
<a name="l00072"></a>00072         }
<a name="l00073"></a>00073         <span class="comment">// read the header data</span>
<a name="l00074"></a>00074         <span class="keywordflow">if</span> (!(valid = readHeaders()))
<a name="l00075"></a>00075                 <span class="keywordflow">return</span>;
<a name="l00076"></a>00076 
<a name="l00077"></a>00077         <span class="comment">// this code only works with single bit data (could be upgraded later on)</span>
<a name="l00078"></a>00078         <span class="keywordflow">if</span> (samplesPerChar!=8) {
<a name="l00079"></a>00079                 errorMsg = <span class="stringliteral">&quot;Sorry, only one bit data is supported&quot;</span>;
<a name="l00080"></a>00080                 valid = <span class="keyword">false</span>;
<a name="l00081"></a>00081                 <span class="keywordflow">return</span>;
<a name="l00082"></a>00082         }
<a name="l00083"></a>00083         <span class="comment">// read the metadata</span>
<a name="l00084"></a>00084         readMetadata();
<a name="l00085"></a>00085         
<a name="l00086"></a>00086         rewind(); <span class="comment">// calls clearBuffer -&gt; allocateBuffer</span>
<a name="l00087"></a>00087 }
<a name="l00088"></a>00088 
<a name="l00095"></a>00095 dsfFileReader::~dsfFileReader()
<a name="l00096"></a>00096 {
<a name="l00097"></a>00097         <span class="comment">// close the file</span>
<a name="l00098"></a>00098         file.close();
<a name="l00099"></a>00099         <span class="comment">// free the mem in the block buffers</span>
<a name="l00100"></a>00100         <span class="keywordflow">if</span> (blockBufferAllocated) {
<a name="l00101"></a>00101                 <span class="keywordflow">for</span> (dsf2flac_uint32 i = 0; i&lt;chanNum; i++)
<a name="l00102"></a>00102                 {
<a name="l00103"></a>00103                         <span class="keyword">delete</span>[] blockBuffer[i];
<a name="l00104"></a>00104                 }
<a name="l00105"></a>00105                 <span class="keyword">delete</span>[] blockBuffer;
<a name="l00106"></a>00106         }
<a name="l00107"></a>00107 }
<a name="l00108"></a>00108 
<a name="l00116"></a>00116 <span class="keywordtype">bool</span> dsfFileReader::step()
<a name="l00117"></a>00117 {
<a name="l00118"></a>00118         <span class="keywordtype">bool</span> ok = <span class="keyword">true</span>;
<a name="l00119"></a>00119         
<a name="l00120"></a>00120         <span class="keywordflow">if</span> (!samplesAvailable())
<a name="l00121"></a>00121                 ok = <span class="keyword">false</span>;
<a name="l00122"></a>00122         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (blockMarker&gt;=blockSzPerChan)
<a name="l00123"></a>00123                 ok = readNextBlock();
<a name="l00124"></a>00124         
<a name="l00125"></a>00125         <span class="keywordflow">if</span> (ok) {
<a name="l00126"></a>00126                 <span class="keywordflow">for</span> (dsf2flac_uint32 i=0; i&lt;chanNum; i++)
<a name="l00127"></a>00127                         circularBuffers[i].push_front(blockBuffer[i][blockMarker]);
<a name="l00128"></a>00128                 blockMarker++;
<a name="l00129"></a>00129         } <span class="keywordflow">else</span> {
<a name="l00130"></a>00130                 <span class="keywordflow">for</span> (dsf2flac_uint32 i=0; i&lt;chanNum; i++)
<a name="l00131"></a>00131                         circularBuffers[i].push_front(getIdleSample());
<a name="l00132"></a>00132         }
<a name="l00133"></a>00133 
<a name="l00134"></a>00134         posMarker++;
<a name="l00135"></a>00135         <span class="keywordflow">return</span> ok;
<a name="l00136"></a>00136 }
<a name="l00137"></a>00137 
<a name="l00138"></a>00138 
<a name="l00145"></a>00145 <span class="keywordtype">void</span> dsfFileReader::rewind()
<a name="l00146"></a>00146 {
<a name="l00147"></a>00147         <span class="comment">// position the file at the start of the data chunk</span>
<a name="l00148"></a>00148         <span class="keywordflow">if</span> (file.seekg(sampleDataPointer)) {
<a name="l00149"></a>00149                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readFirstBlock:file seek error&quot;</span>;
<a name="l00150"></a>00150                 <span class="keywordflow">return</span>;
<a name="l00151"></a>00151         }
<a name="l00152"></a>00152         allocateBlockBuffer();
<a name="l00153"></a>00153         blockCounter = 0;
<a name="l00154"></a>00154         blockMarker = 0;
<a name="l00155"></a>00155         readNextBlock();
<a name="l00156"></a>00156         blockCounter = 0;
<a name="l00157"></a>00157         posMarker = -1;
<a name="l00158"></a>00158         clearBuffer();
<a name="l00159"></a>00159         <span class="keywordflow">return</span>;
<a name="l00160"></a>00160 }
<a name="l00161"></a>00161 
<a name="l00169"></a>00169 <span class="keywordtype">bool</span> dsfFileReader::readNextBlock()
<a name="l00170"></a>00170 {
<a name="l00171"></a>00171         <span class="comment">// return false if this is the end of the file</span>
<a name="l00172"></a>00172         <span class="keywordflow">if</span> (!samplesAvailable()) {
<a name="l00173"></a>00173                 <span class="comment">// fill the blockBuffer with the idle sample</span>
<a name="l00174"></a>00174                 dsf2flac_uint8 idle = getIdleSample();
<a name="l00175"></a>00175                 <span class="keywordflow">for</span> (dsf2flac_uint32 i=0; i&lt;chanNum; i++)
<a name="l00176"></a>00176                         <span class="keywordflow">for</span> (dsf2flac_uint32 j=0; j&lt;blockSzPerChan; j++)
<a name="l00177"></a>00177                                 blockBuffer[i][j] = idle;
<a name="l00178"></a>00178                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00179"></a>00179         }
<a name="l00180"></a>00180 
<a name="l00181"></a>00181         <span class="keywordflow">for</span> (dsf2flac_uint32 i=0; i&lt;chanNum; i++) {
<a name="l00182"></a>00182                 <span class="keywordflow">if</span> (file.read_uint8(blockBuffer[i],blockSzPerChan)) {
<a name="l00183"></a>00183                         <span class="comment">// if read failed fill the blockBuffer with the idle sample</span>
<a name="l00184"></a>00184                         dsf2flac_uint8 idle = getIdleSample();
<a name="l00185"></a>00185                         <span class="keywordflow">for</span> (dsf2flac_uint32 i=0; i&lt;chanNum; i++)
<a name="l00186"></a>00186                                 <span class="keywordflow">for</span> (dsf2flac_uint32 j=0; j&lt;blockSzPerChan; j++)
<a name="l00187"></a>00187                                         blockBuffer[i][j] = idle;
<a name="l00188"></a>00188                         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00189"></a>00189                 }
<a name="l00190"></a>00190         }
<a name="l00191"></a>00191 
<a name="l00192"></a>00192         blockCounter++;
<a name="l00193"></a>00193         blockMarker=0;
<a name="l00194"></a>00194 
<a name="l00195"></a>00195         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00196"></a>00196 }
<a name="l00197"></a>00197 
<a name="l00204"></a>00204 <span class="keywordtype">bool</span> dsfFileReader::readHeaders()
<a name="l00205"></a>00205 {
<a name="l00206"></a>00206         dsf2flac_uint32 chunkStart;
<a name="l00207"></a>00207         dsf2flac_uint64 chunkSz;
<a name="l00208"></a>00208         dsf2flac_int8 ident[4];
<a name="l00209"></a>00209 
<a name="l00210"></a>00210         <span class="comment">// double check that this is the start of the file.</span>
<a name="l00211"></a>00211         <span class="keywordflow">if</span> (file.seekg(0)) {
<a name="l00212"></a>00212                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file seek error&quot;</span>;
<a name="l00213"></a>00213                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00214"></a>00214         }
<a name="l00215"></a>00215 
<a name="l00216"></a>00216         <span class="comment">// DSD CHUNK //</span>
<a name="l00217"></a>00217         chunkStart = file.tellg();
<a name="l00218"></a>00218         <span class="comment">// 4 bytes which should be &quot;DSD &quot;</span>
<a name="l00219"></a>00219         <span class="keywordflow">if</span> (file.read_int8(ident,4)) {
<a name="l00220"></a>00220                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00221"></a>00221                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00222"></a>00222         }
<a name="l00223"></a>00223         <span class="keywordflow">if</span> ( !checkIdent(ident,const_cast&lt;dsf2flac_int8*&gt;(<span class="stringliteral">&quot;DSD &quot;</span>)) ) {
<a name="l00224"></a>00224                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:DSD ident error&quot;</span>;
<a name="l00225"></a>00225                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00226"></a>00226         }
<a name="l00227"></a>00227         <span class="comment">// 8 bytes chunk size</span>
<a name="l00228"></a>00228         <span class="keywordflow">if</span> (file.read_uint64(&amp;chunkSz,1)) {
<a name="l00229"></a>00229                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00230"></a>00230                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00231"></a>00231         }
<a name="l00232"></a>00232         <span class="comment">// 8 bytes file size</span>
<a name="l00233"></a>00233         <span class="keywordflow">if</span> (file.read_uint64(&amp;fileSz,1)) {
<a name="l00234"></a>00234                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00235"></a>00235                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00236"></a>00236         }
<a name="l00237"></a>00237         <span class="comment">// 8 bytes metadata pointer</span>
<a name="l00238"></a>00238         <span class="keywordflow">if</span> (file.read_uint64(&amp;metaChunkPointer,1)) {
<a name="l00239"></a>00239                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00240"></a>00240                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00241"></a>00241         }
<a name="l00242"></a>00242         <span class="comment">// we should be at the end of the DSD chunk now</span>
<a name="l00243"></a>00243         <span class="keywordflow">if</span> ( chunkStart + chunkSz != (dsf2flac_uint64) file.tellg() ) {
<a name="l00244"></a>00244                 <span class="keywordflow">if</span>(file.seekg(chunkStart + chunkSz)) {
<a name="l00245"></a>00245                         errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file seek error&quot;</span>;
<a name="l00246"></a>00246                         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00247"></a>00247                 }
<a name="l00248"></a>00248         }
<a name="l00249"></a>00249 
<a name="l00250"></a>00250         <span class="comment">// FMT CHUNK //</span>
<a name="l00251"></a>00251         chunkStart = file.tellg();
<a name="l00252"></a>00252         <span class="comment">// 4 bytes which should be &quot;fmt &quot;</span>
<a name="l00253"></a>00253         <span class="keywordflow">if</span> (file.read_int8(ident,4)) {
<a name="l00254"></a>00254                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00255"></a>00255                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00256"></a>00256         }
<a name="l00257"></a>00257         <span class="keywordflow">if</span> ( !checkIdent(ident,const_cast&lt;dsf2flac_int8*&gt;(<span class="stringliteral">&quot;fmt &quot;</span>)) ) {
<a name="l00258"></a>00258                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file ident error&quot;</span>;
<a name="l00259"></a>00259                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00260"></a>00260         }
<a name="l00261"></a>00261         <span class="comment">// 8 bytes chunk size</span>
<a name="l00262"></a>00262         <span class="keywordflow">if</span> (file.read_uint64(&amp;chunkSz,1)) {
<a name="l00263"></a>00263                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00264"></a>00264                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00265"></a>00265         }
<a name="l00266"></a>00266         <span class="comment">// 4 bytes format version</span>
<a name="l00267"></a>00267         <span class="keywordflow">if</span> (file.read_uint32(&amp;formatVer,1)) {
<a name="l00268"></a>00268                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00269"></a>00269                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00270"></a>00270         }
<a name="l00271"></a>00271         <span class="comment">// 4 bytes format id</span>
<a name="l00272"></a>00272         <span class="keywordflow">if</span> (file.read_uint32(&amp;formatID,1)) {
<a name="l00273"></a>00273                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00274"></a>00274                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00275"></a>00275         }
<a name="l00276"></a>00276         <span class="comment">// 4 bytes channel type</span>
<a name="l00277"></a>00277         <span class="keywordflow">if</span> (file.read_uint32(&amp;chanType,1)) {
<a name="l00278"></a>00278                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00279"></a>00279                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00280"></a>00280         }
<a name="l00281"></a>00281         <span class="comment">// 4 bytes channel num</span>
<a name="l00282"></a>00282         <span class="keywordflow">if</span> (file.read_uint32(&amp;chanNum,1)) {
<a name="l00283"></a>00283                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00284"></a>00284                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00285"></a>00285         }
<a name="l00286"></a>00286         <span class="comment">// 4 bytes samplingFreq</span>
<a name="l00287"></a>00287         <span class="keywordflow">if</span> (file.read_uint32(&amp;samplingFreq,1)) {
<a name="l00288"></a>00288                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00289"></a>00289                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00290"></a>00290         }
<a name="l00291"></a>00291         <span class="comment">// 4 bytes bitsPerSample</span>
<a name="l00292"></a>00292         dsf2flac_uint32 bitsPerSample = 0;
<a name="l00293"></a>00293         <span class="keywordflow">if</span> (file.read_uint32(&amp;bitsPerSample,1)) {
<a name="l00294"></a>00294                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00295"></a>00295                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00296"></a>00296         }
<a name="l00297"></a>00297         <span class="keywordflow">if</span> (bitsPerSample==1) {
<a name="l00298"></a>00298                 samplesPerChar = 8;
<a name="l00299"></a>00299         } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (bitsPerSample==8) {
<a name="l00300"></a>00300                 samplesPerChar = 1;
<a name="l00301"></a>00301         }
<a name="l00302"></a>00302         <span class="comment">// 8 bytes sampleCount</span>
<a name="l00303"></a>00303         <span class="keywordflow">if</span> (file.read_uint64(&amp;sampleCount,1)) {
<a name="l00304"></a>00304                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00305"></a>00305                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00306"></a>00306         }
<a name="l00307"></a>00307         <span class="comment">// 4 bytes blockSzPerChan</span>
<a name="l00308"></a>00308         <span class="keywordflow">if</span> (file.read_uint32(&amp;blockSzPerChan,1)) {
<a name="l00309"></a>00309                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00310"></a>00310                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00311"></a>00311         }
<a name="l00312"></a>00312         <span class="comment">// 4 bytes ununsed</span>
<a name="l00313"></a>00313         <span class="keywordflow">if</span> (file.seekg(4,fstreamPlus::cur)) {
<a name="l00314"></a>00314                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00315"></a>00315                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00316"></a>00316         }
<a name="l00317"></a>00317         <span class="comment">// we are now at the end of the fmt chunk</span>
<a name="l00318"></a>00318         <span class="keywordflow">if</span> ( chunkStart + chunkSz != (dsf2flac_uint64) file.tellg() ) {
<a name="l00319"></a>00319                 <span class="keywordflow">if</span> (file.seekg(chunkStart + chunkSz)) {
<a name="l00320"></a>00320                         errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file seek error&quot;</span>;
<a name="l00321"></a>00321                         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00322"></a>00322                 }
<a name="l00323"></a>00323         }
<a name="l00324"></a>00324 
<a name="l00325"></a>00325         <span class="comment">// DATA CHUNK //</span>
<a name="l00326"></a>00326         <span class="comment">// 4 bytes which should be &quot;data&quot;</span>
<a name="l00327"></a>00327         <span class="keywordflow">if</span> (file.read_int8(ident,4)) {
<a name="l00328"></a>00328                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00329"></a>00329                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00330"></a>00330         }
<a name="l00331"></a>00331         <span class="keywordflow">if</span> ( !checkIdent(ident,const_cast&lt;dsf2flac_int8*&gt;(<span class="stringliteral">&quot;data&quot;</span>)) ) {
<a name="l00332"></a>00332                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file ident error&quot;</span>;
<a name="l00333"></a>00333                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00334"></a>00334         }
<a name="l00335"></a>00335         <span class="comment">// 8 bytes chunk size</span>
<a name="l00336"></a>00336         <span class="keywordflow">if</span> (file.read_uint64(&amp;dataChunkSz,1)) {
<a name="l00337"></a>00337                 errorMsg = <span class="stringliteral">&quot;dsfFileReader::readHeaders:file read error&quot;</span>;
<a name="l00338"></a>00338                 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00339"></a>00339         }
<a name="l00340"></a>00340         <span class="comment">// store the location of the data</span>
<a name="l00341"></a>00341         sampleDataPointer = file.tellg();
<a name="l00342"></a>00342 
<a name="l00343"></a>00343         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00344"></a>00344 }
<a name="l00345"></a>00345 
<a name="l00353"></a>00353 <span class="keywordtype">void</span> dsfFileReader::allocateBlockBuffer()
<a name="l00354"></a>00354 {
<a name="l00355"></a>00355         <span class="keywordflow">if</span> (blockBufferAllocated)
<a name="l00356"></a>00356                 <span class="keywordflow">return</span>;
<a name="l00357"></a>00357         blockBuffer = <span class="keyword">new</span> dsf2flac_uint8*[chanNum];
<a name="l00358"></a>00358         <span class="keywordflow">for</span> (dsf2flac_uint32 i = 0; i&lt;chanNum; i++)
<a name="l00359"></a>00359                 blockBuffer[i] = <span class="keyword">new</span> dsf2flac_uint8[blockSzPerChan];
<a name="l00360"></a>00360         blockBufferAllocated = <span class="keyword">true</span>;
<a name="l00361"></a>00361 }
<a name="l00362"></a>00362 
<a name="l00370"></a>00370 <span class="keywordtype">void</span> dsfFileReader::readMetadata()
<a name="l00371"></a>00371 {
<a name="l00372"></a>00372 
<a name="l00373"></a>00373         <span class="comment">// zero if no metadata</span>
<a name="l00374"></a>00374         <span class="keywordflow">if</span> (metaChunkPointer == 0) {
<a name="l00375"></a>00375                 <span class="keywordflow">return</span>;
<a name="l00376"></a>00376         }
<a name="l00377"></a>00377 
<a name="l00378"></a>00378         <span class="keywordflow">if</span> (file.seekg(metaChunkPointer)) {
<a name="l00379"></a>00379                 <span class="comment">// if we failed then let&#39;s not worry too much</span>
<a name="l00380"></a>00380                 file.clear();
<a name="l00381"></a>00381                 <span class="keywordflow">return</span>;
<a name="l00382"></a>00382         }
<a name="l00383"></a>00383         
<a name="l00384"></a>00384         <span class="comment">// read the first 10 bytes of the metadata (which should be the header).</span>
<a name="l00385"></a>00385         dsf2flac_uint8 id3header[10];
<a name="l00386"></a>00386         <span class="keywordflow">if</span> (file.read_uint8(id3header,10)) {
<a name="l00387"></a>00387                 <span class="keywordflow">return</span>;
<a name="l00388"></a>00388         }
<a name="l00389"></a>00389         
<a name="l00390"></a>00390         
<a name="l00391"></a>00391         <span class="comment">// check this is actually an id3 header</span>
<a name="l00392"></a>00392         dsf2flac_uint64 id3tagLen;
<a name="l00393"></a>00393         <span class="keywordflow">if</span> ( (id3tagLen = ID3_IsTagHeader(id3header)) &gt; -1 )
<a name="l00394"></a>00394                 <span class="keywordflow">return</span>;
<a name="l00395"></a>00395         <span class="comment">// read the tag</span>
<a name="l00396"></a>00396         dsf2flac_uint8* id3tag = <span class="keyword">new</span> dsf2flac_uint8[ id3tagLen ];
<a name="l00397"></a>00397         <span class="keywordflow">if</span> (file.read_uint8(id3tag,id3tagLen)) {
<a name="l00398"></a>00398                 <span class="keywordflow">return</span>;
<a name="l00399"></a>00399         }
<a name="l00400"></a>00400         
<a name="l00401"></a>00401         metadata.Parse (id3header, id3tag);
<a name="l00402"></a>00402         
<a name="l00403"></a>00403         <span class="keyword">delete</span>[] id3tag;
<a name="l00404"></a>00404 }
<a name="l00405"></a>00405 
<a name="l00412"></a>00412 <span class="keywordtype">bool</span> dsfFileReader::checkIdent(dsf2flac_int8* a, dsf2flac_int8* b)
<a name="l00413"></a>00413 {
<a name="l00414"></a>00414         <span class="keywordflow">return</span> ( a[0]==b[0] &amp;&amp; a[1]==b[1] &amp;&amp; a[2]==b[2] &amp;&amp; a[3]==b[3] );
<a name="l00415"></a>00415 }
<a name="l00416"></a>00416 
<a name="l00423"></a>00423 <span class="keywordtype">void</span> dsfFileReader::dispFileInfo()
<a name="l00424"></a>00424 {
<a name="l00425"></a>00425         printf(<span class="stringliteral">&quot;filesize: %lu\n&quot;</span>,fileSz);
<a name="l00426"></a>00426         printf(<span class="stringliteral">&quot;metaChunkPointer: %lu\n&quot;</span>,metaChunkPointer);
<a name="l00427"></a>00427         printf(<span class="stringliteral">&quot;sampleDataPointer: %lu\n&quot;</span>,sampleDataPointer);
<a name="l00428"></a>00428         printf(<span class="stringliteral">&quot;dataChunkSz: %lu\n&quot;</span>,dataChunkSz);
<a name="l00429"></a>00429         printf(<span class="stringliteral">&quot;formatVer: %u\n&quot;</span>,formatVer);
<a name="l00430"></a>00430         printf(<span class="stringliteral">&quot;formatID: %u\n&quot;</span>,formatID);
<a name="l00431"></a>00431         printf(<span class="stringliteral">&quot;chanType: %u\n&quot;</span>,chanType);
<a name="l00432"></a>00432         printf(<span class="stringliteral">&quot;chanNum: %u\n&quot;</span>,chanNum);
<a name="l00433"></a>00433         printf(<span class="stringliteral">&quot;samplingFreq: %u\n&quot;</span>,samplingFreq);
<a name="l00434"></a>00434         printf(<span class="stringliteral">&quot;samplesPerChar: %u\n&quot;</span>,samplesPerChar);
<a name="l00435"></a>00435         printf(<span class="stringliteral">&quot;sampleCount: %lu\n&quot;</span>,sampleCount);
<a name="l00436"></a>00436         printf(<span class="stringliteral">&quot;blockSzPerChan: %u\n&quot;</span>,blockSzPerChan);
<a name="l00437"></a>00437 
<a name="l00438"></a>00438         <span class="keywordflow">return</span>;
<a name="l00439"></a>00439 }
</pre></div></div><!-- contents -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>



<hr class="footer"/><address class="footer"><small>
Generated on Fri Sep 13 2013 14:42:01 for DSF2FLAC by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.7.6.1
</small></address>

</body>
</html>
